/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bff.core.action.retrieve;

import com.inspur.edp.bef.api.parameter.retrieve.RespectiveRetrieveResult;
import com.inspur.edp.bef.api.parameter.retrieve.RetrieveParam;
import com.inspur.edp.bff.api.dataprocessor.IDataConvertor;
import com.inspur.edp.bff.api.extend.IBffEntityExtend;
import com.inspur.edp.bff.api.extend.IBffManagerExtend;
import com.inspur.edp.bff.spi.AbstractDataConvertor;
import com.inspur.edp.bff.spi.AbstractFSAction;
import com.inspur.edp.cef.entity.accessor.entity.IEntityAccessor;
import com.inspur.edp.cef.entity.entity.IEntityData;
import lombok.var;

import java.util.ArrayList;

public class RetrieveChildAction
        extends AbstractFSAction<IEntityData> {
    private ArrayList<String> nodeCodes;
    private ArrayList<String> lierachyIds;
    private RetrieveParam retrieveParam;

    public RetrieveChildAction(ArrayList<String> nodeCodes, ArrayList<String> lierachyIds, RetrieveParam retrieveParam) {
        this.nodeCodes = nodeCodes;
        this.lierachyIds = lierachyIds;
        this.retrieveParam = retrieveParam;
    }

    protected void execute() {
        if (this.retrieveParam == null) {
            this.retrieveParam = new RetrieveParam();
        }
        RespectiveRetrieveResult retriveResult = getLcp().retrieveChild(this.nodeCodes, this.lierachyIds, this.retrieveParam);
        if (retriveResult.getData() == null) {
            setResult(null);
        } else {
            IEntityData vmData = null;
            boolean isHasExtend = isExtend();
            if (!isHasExtend)
                vmData = getContext().createData((String) this.nodeCodes.get(this.nodeCodes.size() - 1));
            else {
                Object tempVar = getContext().getBffManager().createChildData(nodeCodes.get(nodeCodes.size() - 1), "");
                IEntityAccessor vmAccessor = (IEntityAccessor) ((tempVar instanceof IEntityAccessor) ? tempVar : null);
                vmData = (IEntityData) ((vmAccessor.getInnerData() instanceof IEntityData) ? vmAccessor.getInnerData() : null);
            }
            IEntityData beData = retriveResult.getData();
            getDataConvertor().convertFromBEData(beData, vmData);
            if (isHasExtend) {
                dealExtendMapping(vmData, beData);
            }
            setResult(vmData);
        }
    }

    private boolean isExtend() {
        if (this.getContext().getExtList() == null || this.getContext().getExtList().size() == 0)
            return false;
        return true;
    }

    private void dealExtendMapping(IEntityData voData, IEntityData beData) {
        var extList = getContext().getExtList();
        if (extList == null || extList.size() < 1)
            return;
        for (var ext : extList) {
            IBffEntityExtend entityExtend = getChildEntityExtend(ext);
            if (entityExtend != null)
                entityExtend.mapData2Vo(voData, beData);
        }
    }

    private IBffEntityExtend getChildEntityExtend(IBffManagerExtend mgrExtend) {

        IBffEntityExtend entityExtend = mgrExtend.getDataTypeExtend();
        for (String nodeCode : nodeCodes) {
            entityExtend = entityExtend.getChildEntity(nodeCode);
            if (entityExtend == null)
                break;
        }
        return entityExtend;
    }

    private AbstractDataConvertor getDataConvertor() {
        IDataConvertor dataConvertor = getContext().getDataConvertor();
        AbstractDataConvertor rootConvertor = (AbstractDataConvertor) ((dataConvertor instanceof AbstractDataConvertor) ? dataConvertor : null);
        if (this.nodeCodes.isEmpty()) {
            return rootConvertor;
        }
        AbstractDataConvertor currentConvertor = rootConvertor;
        for (int i = 0; i < this.nodeCodes.size(); i++) {
            currentConvertor = currentConvertor.getChildDataConvertor((String) this.nodeCodes.get(i));
        }
        return currentConvertor;
    }
}
